package com.wosiliujing.learning.route.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wosiliujing.learning.route.entity.SysRouteConfig;
import com.wosiliujing.learning.constant.CommonConstants;
import com.wosiliujing.learning.gateway.event.DynamicRouteInitEvent;
import com.wosiliujing.learning.route.mapper.SysRouteConfigMapper;
import com.wosiliujing.learning.route.service.SysRouteConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/***
 * @author 刘靖
 * @date 2019/7/115:56
 */
@Service
@Slf4j
@AllArgsConstructor
public class SysRouteConfigServiceImpl extends ServiceImpl<SysRouteConfigMapper,SysRouteConfig> implements SysRouteConfigService {

    private final ApplicationEventPublisher applicationEventPublisher;

    @Override
    public List<SysRouteConfig> listRoute() {
        return this.baseMapper.selectList(Wrappers.emptyWrapper());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Mono<Void> updateRoutes(JSONArray routes) {
        SysRouteConfig condition = new SysRouteConfig();
        condition.setDelFlag(CommonConstants.NORMAL_STATUS);
        this.remove(new UpdateWrapper<>(condition));
        List<SysRouteConfig> routeList = new ArrayList<>();
        routes.forEach(route -> {
            log.info("更新路由 ->{}", route);
            Map map = (Map) route;
            SysRouteConfig sysRouteConfig = new SysRouteConfig();
            sysRouteConfig.setRouteId(map.get("routeId").toString());
            sysRouteConfig.setDelFlag(CommonConstants.NORMAL_STATUS);
            sysRouteConfig.setRouteName(map.get("routeName").toString());
            Object predicates = map.get("predicates");
            if(ObjectUtil.isNotEmpty(predicates)){
                JSONArray jsonArray = (JSONArray)predicates;
                List<PredicateDefinition> predicateDefinitions = jsonArray.toList(PredicateDefinition.class);
                sysRouteConfig.setPredicates(JSONUtil.toJsonStr(predicateDefinitions));
            }
            Object filters = map.get("filters");
            if (ObjectUtil.isNotEmpty(filters)) {
                JSONArray jsonArray = (JSONArray)filters;
                List<FilterDefinition> filterDefinitionList
                        = jsonArray.toList(FilterDefinition.class);
                sysRouteConfig.setFilters(JSONUtil.toJsonStr(filterDefinitionList));
            }
            sysRouteConfig.setUrl(map.get("url").toString());
            sysRouteConfig.setOrder(ObjectUtil.isEmpty(map.get("order"))?0:Integer.parseInt(map.get("order").toString()));
            sysRouteConfig.setCreateTime(LocalDateTime.now());
            routeList.add(sysRouteConfig);
        });
        this.saveBatch(routeList);
        log.debug("更新网关路由结束 ");
        this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this));
        return Mono.empty();
    }
}
